#ifndef __xwt_window_h
  #define __xwt_window_h

#include <xwt/xwt_defs.h>
#include <xwt/xwt_graphics.h>
#include <sysport/sysport.h>

XWT_BEGIN_NAMESPACE(xwt)

enum MouseButton {
	InvalidButton = -1,
	LeftButton = 0,
	RightButton = 1,
	CenterButton = 2
};

/** A base genreic window... */
class Window {
public:
	Window ();
	virtual ~Window ();

public:
	// window creation...
	virtual bool Create (int x, int y, int cx, int cy, const sys_tchar *title);
	virtual bool Create (const Rect &rect, const sys_tchar *title) {
		return Create (rect.left, rect.top, rect.width, rect.height, title);
	}
	virtual void Destroy ();

	// operations...
public:
	XWTWND GetHandle () const {
		return m_hWnd;
	}
	void AttachHandle (XWTWND handle);
	XWTWND DetachHandle ();
	void Show ();
	void Update ();
	void Hide ();
	bool IsValid () const;
	bool IsVisible () const;
	long GetData () const {
		return m_userData;
	}	
	void SetData (long data) {
		m_userData = data;
	}
	void SetAsMainWindow (bool flag = true) {
		m_isMainWnd = flag;
	}
	void SetOpacity (float opacity);
	void AddChild (Window *childWnd);
	XWTWND GetParentHandle () {
	#ifdef WIN32
		return ::GetParent(m_hWnd);
	#endif
	}
	Rect GetWindowRect () const;
	Rect GetClientRect () const;
	void Resize (const Rect &rect, bool force_repaint = false);
	void CenterWindow (Window *pParent = NULL);
	void SetBackgroundColor (const Color &color);
	void SetTitleText (sys_tchar *text);
	void EnableDropTarget (bool flag_enable = true, unsigned max = 0);

	// helpers...
protected:
	inline void MapHandle ();
	inline void UnmapHandle ();

	// overridables...
#ifdef WIN32
	virtual void GetCreateStyle (DWORD &dwStyle, DWORD &dwExStyle);
	virtual void GetClassStyle (WNDCLASSEX &wcex);
	virtual LRESULT HandleMessage (UINT msg, WPARAM wParam, LPARAM lParam);
	virtual INT_PTR HandleDialogMessage (UINT msg, WPARAM wParam, LPARAM lParam);

	// window procedure callback
	static LRESULT CALLBACK _wndProc (HWND, UINT, WPARAM, LPARAM);
	// dialog box window procedure callback
	static INT_PTR _dlgProc (HWND, UINT, WPARAM, LPARAM);
#endif

	// message handlers...
protected:
	//XWT_DECL_MESSAGE_HANDLER(WM_CREATE)
	XWT_DECL_MESSAGE_HANDLER(WM_NCDESTROY)
	XWT_DECL_MESSAGE_HANDLER(WM_DESTROY)
	XWT_DECL_MESSAGE_HANDLER(WM_ERASEBKGND)
	XWT_DECL_MESSAGE_HANDLER(WM_LBUTTONDOWN)
	XWT_DECL_MESSAGE_HANDLER(WM_LBUTTONUP)
	XWT_DECL_MESSAGE_HANDLER(WM_RBUTTONDOWN)
	XWT_DECL_MESSAGE_HANDLER(WM_RBUTTONUP)
	XWT_DECL_MESSAGE_HANDLER(WM_MOUSEMOVE)
	XWT_DECL_MESSAGE_HANDLER(WM_MOUSELEAVE)
	XWT_DECL_MESSAGE_HANDLER(WM_CHAR)
	XWT_DECL_MESSAGE_HANDLER(WM_KEYDOWN)
	XWT_DECL_MESSAGE_HANDLER(WM_KEYUP)
	XWT_DECL_MESSAGE_HANDLER(WM_PAINT)
	XWT_DECL_MESSAGE_HANDLER(WM_SIZE)
	XWT_DECL_MESSAGE_HANDLER(WM_SETFOCUS)
	XWT_DECL_MESSAGE_HANDLER(WM_KILLFOCUS)
	XWT_DECL_MESSAGE_HANDLER(WM_CONTEXTMENU)
	XWT_DECL_MESSAGE_HANDLER(WM_COMMAND)
	XWT_DECL_MESSAGE_HANDLER(WM_DROPFILES)
	XWT_DECL_MESSAGE_HANDLER(WM_CLOSE)	
	
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_MOUSEMOVE)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_MOUSELEAVE)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_LBUTTONDOWN)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_LBUTTONUP)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_RBUTTONDOWN)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_RBUTTONUP)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_CHAR)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_KEYDOWN)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_KEYUP)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_NCDESTROY)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_DESTROY)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_SIZE)	
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_SETFOCUS)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_KILLFOCUS)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_COMMAND)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_CONTEXTMENU)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_INITDIALOG)
	// XWT_DECL_DLG_MESSAGE_HANDLER(WM_CREATE)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_ERASEBKGND)
	XWT_DECL_DLG_MESSAGE_HANDLER(WM_PAINT)
	// XWT_DECL_DLG_MESSAGE_HANDLER(WM_DROPFILES)
	// XWT_DECL_DLG_MESSAGE_HANDLER(WM_CLOSE)

	// event handlers...
	XWT_DECL_EVENT_HANDLER(Create) ();
	XWT_DECL_EVENT_HANDLER(InitDialog) () {}
	XWT_DECL_EVENT_HANDLER(PreDestroy) () {}
	XWT_DECL_EVENT_HANDLER(Destroy) () {}
	XWT_DECL_EVENT_HANDLER(EraseBackground) (GC &gc);
	XWT_DECL_EVENT_HANDLER(MouseDown) (int button, int x, int y) {}
	XWT_DECL_EVENT_HANDLER(MouseUp) (MouseButton button, int x, int y) {}
	XWT_DECL_EVENT_HANDLER(MouseMove) (MouseButton button, int x, int y) {}
	XWT_DECL_EVENT_HANDLER(MouseLeave) () {}
	XWT_DECL_EVENT_HANDLER(KeyPress) (int virtkey, int rpt_ctr) {}
	XWT_DECL_EVENT_HANDLER(KeyDown) (int virtkey) {}
	XWT_DECL_EVENT_HANDLER(KeyUp) (int virtkey) {}
	XWT_DECL_EVENT_HANDLER(Paint) (GC &gc) {}
	XWT_DECL_EVENT_HANDLER(Resize) (int cx, int cy) {}
	XWT_DECL_EVENT_HANDLER(GotFocus) () {}
	XWT_DECL_EVENT_HANDLER(LostFocus) () {}
	XWT_DECL_EVENT_HANDLER(ContextMenu) () {}
	XWT_DECL_EVENT_HANDLER(Command) (int cmdid);
	XWT_DECL_EVENT_HANDLER(DropFiles) (const std::list<tstring> &list_dropped_files) {}
	XWT_DECL_EVENT_HANDLER(Close) (bool &cancel) {}

	// data members...
protected:
	XWTWND		m_hWnd;
	bool		m_isMainWnd;
	bool		m_isDialog;
	long		m_userData;
	bool		m_flagMouseTracking;
	unsigned	m_dropTargetMax;
	Color		m_bg_color;
	float		m_opacity;
};

XWT_END_NAMESPACE(xwt);

#endif /* __xwt_window_h */
